package com.crm.service.before_sale.impl;

import com.crm.dao.before_sale.PlanDetailsDAO;
import com.crm.dao.before_sale.SalePlanDAO;
import com.crm.exception.ServiceException;
import com.crm.pojo.Contract;
import com.crm.pojo.PlanDetail;
import com.crm.pojo.SaleChance;
import com.crm.pojo.SalePlan;
import com.crm.service.before_sale.SalePlanService;
import com.crm.vo.Result;
import com.crm.vo.SalePlanDetailsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by dr5hx on 2018/8/9
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SalePlanServiceImpl implements SalePlanService {
    @Autowired
    private SalePlanDAO salePlanDAO;
    @Autowired
    private PlanDetailsDAO planDetailsDAO;

    /**
     * 返回对应用户的销售计划表
     *
     * @param cid
     * @return
     */
    @Override
    public List<SalePlan> showCustomerPlan(Long cid) {

        return salePlanDAO.showCustomerPlan(new BigDecimal(cid));
    }

    /**
     * 删除销售计划
     *
     * @param planId
     * @return
     */
    @Override
    public Result deleteSalePlanById(Long planId) {
        try {
            salePlanDAO.deleteSalePlanById(planId);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(e);
        }


    }

    /**
     * 分页展示销售计划
     *
     * @param salePlan
     * @param curpage
     * @param pagesize
     * @param minMoney
     * @param maxMoney
     * @param createStartTime
     * @param createEndTime
     * @param updateStartTime
     * @param updateEndTime
     * @return
     */
    @Override
    public List<SalePlan> getSalePlanList(SalePlan salePlan, int curpage, int pagesize,
                                          BigDecimal minMoney, BigDecimal maxMoney, Date createStartTime, Date createEndTime,
                                          Date updateStartTime, Date updateEndTime) {
        Assert.notNull(salePlan);
        PageRequest pageRequest = new PageRequest(curpage - 1, pagesize, Sort.Direction.DESC, "planId");
        @SuppressWarnings("unchecked")
        Page<SalePlan> result = salePlanDAO.findAll(new Specification<SalePlan>() {
            @Override
            public Predicate toPredicate(Root<SalePlan> root, CriteriaQuery<?> argl, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                //根据以下条件查询
                //1.负责人
                if (salePlan.getUserId() != null) {
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class), salePlan.getUserId()));
                }
                //2.审核状态
                if (!StringUtils.isEmpty(salePlan.getPlanCheck())) {
                    list.add(cb.like(root.get("planCheck").as(String.class), "%" + salePlan.getPlanCheck() + "%"));
                }
                //3.项目名称
                if (!StringUtils.isEmpty(salePlan.getPlanName())) {
                    list.add(cb.like(root.get("planName").as(String.class), "%" + salePlan.getPlanName() + "%"));
                }
                //没有被删除
                list.add(cb.notLike(root.get("salePlanIsDel").as(String.class), "是"));

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        }, pageRequest);
        List<SalePlan> list = result.getContent();
        return list;
    }

    /**
     * 获取销售计划总数量
     *
     * @param salePlan
     * @param minMoney
     * @param maxMoney
     * @param createStartTime
     * @param createEndTime
     * @param updateStartTime
     * @param updateEndTime
     * @return
     */
    @Override
    public Long getSalePlanCount(SalePlan salePlan, BigDecimal minMoney, BigDecimal maxMoney,
                                 Date createStartTime, Date createEndTime, Date updateStartTime, Date updateEndTime) {
        Assert.notNull(salePlan);
        Long total = salePlanDAO.count(new Specification<SalePlan>() {
            @Override
            public Predicate toPredicate(Root<SalePlan> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                //根据以下条件查询
                //1.负责人
                if (salePlan.getUserId() != null) {
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class), salePlan.getUserId()));
                }
                //2.审核状态
                if (!StringUtils.isEmpty(salePlan.getPlanCheck())) {
                    list.add(cb.like(root.get("planCheck").as(String.class), "%" + salePlan.getPlanCheck() + "%"));
                }
                //3.项目名称
                if (!StringUtils.isEmpty(salePlan.getPlanName())) {
                    list.add(cb.like(root.get("planName").as(String.class), "%" + salePlan.getPlanName() + "%"));
                }
                //没有被删除
                list.add(cb.notLike(root.get("salePlanIsDel").as(String.class), "是"));
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        });

        return total;
    }

    /**
     * 展示一个销售计划对应的计划明细
     *
     * @param planId
     * @return
     */
    @Override
    public List<SalePlanDetailsVO> getSalePlanDetailsList(Long planId) {
        SalePlan salePlan = salePlanDAO.findOne(planId);
        return salePlanDAO.getSalePlanDetatils(salePlan);
    }

    @Override
    public SalePlan findOneSalePlanById(Long id) {
        return salePlanDAO.findOne(id);
    }

    /**
     * 根据id获取一条计划明细
     * @param saleDetId
     * @return
     */
    @Override
    public SalePlanDetailsVO getOnePlanDetails(Long saleDetId) {
        return salePlanDAO.getOnePlanDetails(saleDetId);
    }



    /**
     * 添加一个销售计划
     *
     * @param planName
     * @param userId
     * @param planCheck
     * @param strategyProduct
     * @param strategyPrice
     * @param expenseBudget
     * @throws ServiceException
     */
    @Override
    public SalePlan addSalePlan(String planName, BigDecimal userId, String planCheck, String strategyProduct, String strategyPrice,
                                BigDecimal expenseBudget, Date setTime, Date updateDate) throws ServiceException {
        try {
            SalePlan salePlan = new SalePlan();
            salePlan.setPlanName(planName);
            salePlan.setUserId(userId);
            salePlan.setPlanCheck(planCheck);
            salePlan.setStrategyProduct(strategyProduct);
            salePlan.setStrategyPrice(strategyPrice);
            salePlan.setExpenseBudget(expenseBudget);
            salePlan.setSetTime(new Date());
            salePlan.setUpdateDate(new Date());
            salePlan.setSalePlanIsDel("否");
            salePlanDAO.save(salePlan);
            return salePlan;


        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }


    }

    /**
     * 添加计划明细
     *
     * @param planDetail
     * @param id
     */
    @Override
    public void addPlanDetails(PlanDetail planDetail, Long id) {

        try {
            SalePlan s = salePlanDAO.findOne(id);
            planDetail.setSalePlan(s);
            planDetail.setPlanDetailIsDel("否");
            planDetailsDAO.save(planDetail);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }

    }

    /**
     * 保存修改的计划明细
     * @param planDetail
     * @return
     */
    @Override
    public PlanDetail savePlanDetails(PlanDetail planDetail) {
        return planDetailsDAO.save(planDetail);
    }

    /**
     * 获取一个计划下的明细列表
     * @param planId
     * @return
     */
    @Override
    public List<SalePlanDetailsVO> getPlanDetailsList(Long planId) {
        SalePlan salePlan = salePlanDAO.findOne(planId);
        return planDetailsDAO.getPlanDetailsListBySalePlanId(salePlan);
    }

    /**
     * 删除计划明细
     * @param saleDetId
     * @return
     */
    @Override
    public Result deletePlanDetails(Long saleDetId) throws ServiceException{
        try {
            planDetailsDAO.deleteSalePlanDetails(saleDetId);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("Sorry,删除失败!");
        }
    }

    /**
     * 编辑计划
     * @param salePlan
     * @return
     */
    @Override
    public Result editSalePlan(SalePlan salePlan) {
        try {
            salePlan.setUpdateDate(new Date());
            salePlanDAO.save(salePlan);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("Sorry,编辑失败!");
        }
    }

    @Override
    public List<PlanDetail> savePlanDetails(List<PlanDetail> list) throws ServiceException {
        try {
            Iterable iterable = planDetailsDAO.save(list);
            List<PlanDetail> planDetailList = new ArrayList<>();
            iterable.forEach(e -> planDetailList.add((PlanDetail) e) );
            return planDetailList;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }
    }

    @Override
    public Result newDeletePlanDetail(PlanDetail planDetail) {
        try {
            planDetail.setPlanDetailIsDel("是");
            planDetailsDAO.save(planDetail);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return  new Result(e);
        }
    }


}
